package recompiled;

/**
 * TARGET PC: 0xA00000D0
 */
public class A00000D0 extends compiler.BasicBlock {

	private static final A00000D0 INSTANCE = new A00000D0();

	private A00000D0(){}

	/**
	 * @see compiler.BasicBlock#getBasicBlock 
	 */
	public static compiler.BasicBlock getBasicBlock() {
		return INSTANCE;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void execute() throws mips.exceptions.MipsException {

		//0xa00000d0 
		//0x8fc20010 
		//LW
		mips.CPU.GPR[2] = n64.MemoryManager.readWord(mips.CPU.GPR[30] + 16);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000d4 
		//0x03c0e820 
		//ADD
		u32_gpr_rs = mips.instructions.Instruction.zeroExtendW(mips.CPU.GPR[30]);
		u32_gpr_rt = mips.instructions.Instruction.zeroExtendW(mips.CPU.GPR[0]);
		
		if (u32_gpr_rs + u32_gpr_rt > 4294967295L) {
			throw new mips.exceptions.OverflowException(mips.CPU.PC,0x03C0E820);
		} 
		else {
			mips.CPU.GPR[29] = mips.CPU.GPR[30] + mips.CPU.GPR[0];
		}
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000d8 
		//0x8fbf0020 
		//LW
		mips.CPU.GPR[31] = n64.MemoryManager.readWord(mips.CPU.GPR[29] + 32);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000dc 
		//0x8fbe001c 
		//LW
		mips.CPU.GPR[30] = n64.MemoryManager.readWord(mips.CPU.GPR[29] + 28);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000e0 
		//0x8fb00018 
		//LW
		mips.CPU.GPR[16] = n64.MemoryManager.readWord(mips.CPU.GPR[29] + 24);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000e4 
		//0x27bd0028 
		//ADDIU
		u32_gpr_rs = mips.instructions.Instruction.zeroExtendW(mips.CPU.GPR[29]); 
		
		mips.CPU.GPR[29] = (int)((u32_gpr_rs + 40) & 4294967295L);
		
		mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;


		//0xa00000e8 
		//0x03e00008 
		//JR
		if ((mips.CPU.GPR[31] & 0x00000003) == 0) {
			
			mips.CPU.PC = mips.CPU.nPC;
			mips.CPU.nPC = mips.CPU.GPR[31];
		} 
		else {
			throw new mips.exceptions.AddressErrorException(mips.CPU.PC,0x03E00008);
		}


		if(!skipDelaySlot) {
			//0xa00000ec 
			//0x00000020 
			//NOP
			mips.CPU.PC = mips.CPU.nPC;
		mips.CPU.nPC = mips.CPU.PC + 4;

		}
		
	}

	public static int instructionLength = 8;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int blockLength() {
		int returnLen = instructionLength;
		if(skipDelaySlot) {
			returnLen -= 1;
			skipDelaySlot = false;
		}
		return returnLen;
	}
}

